#ifndef MEASUREMENTALGORITHMMANAGER_H
#define MEASUREMENTALGORITHMMANAGER_H

#include <QObject>
#include <QMap>
#include <QString>
#include <QPluginLoader>
#include <QVariantMap>
#include <QImage>
#include "MeasurementAlgorithmBase.h"

/**
 * @brief 测量算法管理器
 * 负责加载、管理和协调所有测量算法插件，提供统一的算法接口访问机制。
 * 管理算法的生命周期、参数设置和测量执行流程，实现算法的即插即用功能。
 */
class MeasurementAlgorithmManager : public QObject
{
    Q_OBJECT
public:
    /**
     * @brief 构造函数
     * 初始化测量算法管理器，自动加载默认目录下的所有测量算法
     * @param parent 父对象指针
     */
    explicit MeasurementAlgorithmManager(QObject *parent = nullptr);
    
    /**
     * @brief 析构函数
     * 释放所有加载的算法实例和插件加载器资源
     */
    ~MeasurementAlgorithmManager();

    /**
     * @brief 初始化管理器
     * 获取应用程序目录，构建算法插件目录路径并加载算法
     */
    void initialize();

    /**
     * @brief 获取所有加载的算法
     * @return 包含所有算法名称和对应实例的映射表
     */
    QMap<QString, MeasurementAlgorithmBase*> algorithms() const;

    /**
     * @brief 根据名称获取算法实例
     * @param name 算法名称
     * @return 算法实例指针，如果未找到则返回nullptr
     */
    MeasurementAlgorithmBase* getAlgorithm(const QString& name) const;

    /**
     * @brief 从指定目录加载测量算法DLL插件
     * @param dllPath 包含算法DLL的目录路径
     */
    void loadAlgorithm(const QString &dllPath);

    /**
     * @brief 使用指定算法对指定图像执行测量
     * @param algorithmName 算法名称
     * @param imageGuid 待测量图像的唯一标识符
     */
    void processMeasurement(const QString& algorithmName, const QString& imageGuid);

    /**
     * @brief 结束指定算法对指定图像执行测量
     * @param algorithmName 算法名称
     */
    void endProcessMeasurement(const QString& algorithmName);

    /**
     * @brief 设置处理指定图像的所有算法的缩放比例
     * @param imageGuid 图像guid
     * @param scale 缩放比例值
     */
    void setScaleForAlgorithm(const QString & imageGuid,double scale);
    
    /**
     * @brief 设置处理指定图像的所有算法的单位转换信息
     * @param imageGuid 待测量图像的唯一标识符
     * @param xUnit X轴单位
     * @param yUnit Y轴单位
     * @param lengthRatio 长度单位转换比例
     * @param timeRatio 时间单位转换比例
     * @param wavelengthRatio 波长单位转换比例
     * @param lengthUnit 长度单位
     * @param timeUnit 时间单位
     * @param wavelengthUnit 波长单位
     */
    void setUnitConversionForAlgorithm(const QString & imageGuid,
                                      const QString& xUnit, const QString& yUnit,
                                      double lengthRatio, double timeRatio, double wavelengthRatio,
                                      const QString& lengthUnit, const QString& timeUnit, const QString& wavelengthUnit);
    
    /**
     * @brief 设置指定算法的参数
     * @param algorithmName 算法名称
     * @param imageGuid 待测量图像的唯一标识符
     * @param params 包含算法参数的QVariantMap
     */
    void setAlgorithmParameters(const QString& algorithmName, const QString & imageGuid, const QVariantMap& params);

    /**
     * @brief 获取指定算法的当前参数
     * @param algorithmName 算法名称
     * @return 包含算法参数的QVariantMap，如果未找到算法则返回空映射
     */
    QVariantMap getAlgorithmParameters(const QString& algorithmName);
    
    /**
     * @brief 获取指定算法支持的测量模式
     * @param algorithmName 算法名称
     * @return 算法支持的测量模式集合，如果未找到算法则返回MeasurementMode::None
     */
    MeasurementModes getSupportedModes(const QString& algorithmName) const;
    
    /**
     * @brief 设置指定算法的测量结果
     * 用于撤销/重做操作时直接恢复测量结果
     * @param algorithmName 算法名称
     * @param measurementResult 测量结果数据
     */
    void setMeasurementResult(const QString& algorithmName, const QVariantMap& measurementResult);

signals:
    /**
     * @brief 测量完成信号
     * 当算法完成测量后发出，包含图像ID、测量结果和算法名称
     * @param imageGuid 图像唯一标识符
     * @param measurementResult 测量结果数据
     * @param algorithmName 执行测量的算法名称
     */
    void measurementProcessingCompleted(const QString& imageGuid, const QVariantMap& measurementResult, const QString& algorithmName);
    
    /**
     * @brief 算法注册完成信号
     * 当新算法注册后发出，用于UI显示算法按钮
     * @param algorithmName 算法名称
     * @param iconPath 算法图标路径
     */
    void algorithmRegistered(const QString& algorithmName, const QString& iconPath);
    
    /**
     * @brief 结果显示widget就绪信号
     * 当算法结果显示widget注册后发出，用于显示结果界面
     * @param algorithmName 算法名称
     * @param widget 结果显示widget指针
     */
    void resultWidgetReady(const QString& algorithmName, QWidget* widget);
    
    /**
     * @brief 注册测量工具widget信号
     * 当算法注册自定义测量工具widget时发出
     * @param algorithmName 算法名称
     * @param widget 测量工具widget指针
     */
    void measurementToolWidgetRegistered(const QString& algorithmName, QWidget* widget);
    
private:
    /**
     * @brief 存储所有加载的算法实例
     * key: 算法名称, value: 算法实例指针
     */
    QMap<QString, MeasurementAlgorithmBase*> m_algorithms;

    /**
     * @brief 存储所有插件加载器
     * key: 算法名称, value: 插件加载器指针
     */
    QMap<QString, QPluginLoader*> m_loaders;

};

#endif // MEASUREMENTALGORITHMMANAGER_H
